<?php
/*
    To upload files:
    use in conjunction with multiple_upload.js

        $fileManager = new FileManager();

        $fileManager->setDBLink($dbLink);
        if($parentObj->file_managerID)
        {
            $fileManager->get($parentObj->file_managerID);
        }
        else
        {
            $fileManager->create();
            $parentObj->file_managerID = $fileManager->getID();
            $parentObj->update();
        }

        $fileManager->uploadMultiple($_FILES);
*/

class FileManager extends DataObjectWed
{
    protected $_itemBuilderClass = 'FileManagerItemBuilder';
    
    public $fileAttr = array();
    public $ownUploadFolder = false;
    public $allowedMediaTypes = array();
    public $_arFMItems = array(); // array containing FileManagerItem objects.
    // need to be done manually, since fileManagerItem extended classes have different delete functions.
    //protected $_arDependantClasses = array("FileManagerItem");
    protected $_type = 'generic';
    protected $_defaultFiletype = '';

    public $_dbTable = 'file_manager';
    public $_dbIndex = 'file_managerID';
    public $_arFields = array('type',
                              'name',
                              'description',
                              'main_itemID',
                              'restricted',
                              'active');

    public function __construct($fileAttr = array())
    {
        parent::__construct();
        $this->type = $this->_type;
        $this->fileAttr = $fileAttr;
    }

    public function get($opt)
    {
        return parent::get($opt) && $this->load();
    }
    
    public function delete($opt)
    {
        if(parent::delete($opt))
        {
            $this->load();
            foreach($this->_arFMItems as $fileManagerItem)
            {
                $fileManagerItem->delete();
            }
            return 1;
        }
    }
    
    public function duplicate($id = NULL)
    {
        $newObj = parent::duplicate($id);
        if($newObj->getID())
        {
            $this->load();
            foreach($this->_arFMItems as $fileManagerItem)
            {
                $newItem = $fileManagerItem->duplicate();
                $newItem->file_managerID = $newObj->getID();
                $newItem->update();
            }
        }
    }
    
    // Loading FMI into FileManager
    public function load()
    {
        $this->_arFMItems = array();
        if($this->ownUploadFolder)
            $this->fileAttr['file_folder'] = $this->fileAttr['file_folder'] ? $this->fileAttr['file_folder'] : $this->getID();
        $sql = "SELECT * FROM file_manager_item WHERE ". $this->_dbIndex ."='". $this->getID() ."' ORDER BY `order` ASC ";
        if ($this->_mysqlQuery($sql, $result))
        {
            while($row = mysql_fetch_assoc($result))
            {
                $builder = $this->_itemBuilderClass;
                $FMIBuilder = new $builder();
                $fmi = $FMIBuilder->build($row["type"], $this->fileAttr);
                $fmi->setDBLink($this->_dbLink);
                $fmi->set($row);
                array_push($this->_arFMItems, $fmi);
            }
            return 1;
        }
        return 0;
    }

    // Operating with FMI
    public function upload($filePost, $options=array())
    {   
        if(!$this->getID() || !$this->fileTypeAllowed($filePost['type'])) return 0;
        $type=$options["type"]? $options["type"] : $this->_defaultFiletype;
        if($options["fileAttr"])
        {
            $fileAttr = array_merge($this->fileAttr,$options["fileAttr"]);
            $fileAttr['file_folder'] = $this->fileAttr['file_folder'];
        }
        else
        {
            $fileAttr = $this->fileAttr;
        }
        $builder = $this->_itemBuilderClass;
        $FMIBuilder = new $builder();
        $fmi = $FMIBuilder->build($type, $fileAttr);
        $fmi->setDBLink($this->_dbLink);
        $fmi->file_managerID = $this->getID();
        $fmi->userID_modified = $this->userID_modified;
        if ($fmi->create() && $fmi->upload($filePost))
        {
            array_push($this->_arFMItems, $fmi);  
            return $fmi->getID();
        }
        return 0;
    }

    public function uploadMultiple($filesPost, $prefix = "", $opts = array())
    {
        if(is_array($filesPost['files']))
        {
            /*
                array comes as:
                [name] => Array
                (
                    [N] => (last one always empty)
                        ...
                    [1] => filename1
                    [0] => filename0
                )
                [type] => Array
                (
                    [N] =>
                        ...
                    [1] => application/zip
                    [0] => application/x-rar-compressed
                )
                ...
                matrix must be reverted (files containing attributes, not attributes containing files)
            */
            $files = array();
            foreach($filesPost['files'] as $attrName => $attr)
            {   
                foreach($attr as $fileNo => $value)
                {
                    if(!$filesPost['files']['error'][$prefix.'multiple_file'][$fileNo]) $files[$fileNo][$attrName] = $value[0];
                }
            }

            foreach($files as $file)
            {
                $options = $opts[$prefix.'multiple_file'] ? $opts[$prefix.'multiple_file'] : array();
                $this->upload($file, $options);
            }
        }
    }

    public function remove($fileID)
    {
        if(!$fileID)
        {
            $this->_error("Por favor, seleccione un archivo.");
            return 0;
        }
        foreach($this->_arFMItems as $key => $fmi)
        {
            if ($fmi->getID()==$fileID)
            {
                if ($fmi->delete())
                {
                    unset($this->_arFMItems[$key]);
                    return 1;
                }
                else $this->_error("Error al eliminar archivo: ". $fmi->getErrorMessage());
            }
        }
        return 0;
    }

    public function removeMultiple($post)
    {
        if(is_array($post['delFile']))
            foreach($post['delFile'] as $fileID => $value)
                $this->remove($fileID);
        return 1;
    }

    public function download($itemID)
    {
        if($fmi = $this->getItem($itemID)) return $fmi->download();
    }

    protected function getItem($itemID)
    {
        if(!$itemID)
        {
            $this->_error("Por favor, seleccione un archivo.");
            return 0;
        }
        foreach($this->_arFMItems as $fmi)
            if ($fmi->getID()==$itemID) return $fmi;

        return 0;
    }

    public function getAll($force = false)
    {
        if ($force) $this->load();
        return $this->_arFMItems;
    }

    // checks if a file type is allowed in the file manager.
    protected function fileTypeAllowed($type)
    {
        if(!count($this->allowedMediaTypes)) return 1;
        $type = explode("/",$type);
        return in_array($type[0], $this->allowedMediaTypes) || in_array($type[1], $this->allowedMediaTypes);
    }
    
}
?>
